"""
Backend response times statistics are collected and reported by
``Stats``.

    >>> stats = Stats()

Record some example response times for a backend.

    >>> stats.record(0.0, '127.0.0.1:8080', 1.0)
    >>> stats.record(60.0, '127.0.0.1:8080', 10.0)
    >>> stats.record(120.0, '127.0.0.1:8080', 2.0)
    >>> stats.record(180.0, '127.0.0.1:8080', 0.5)
    >>> stats.record(240.0, '127.0.0.1:8080', 4.0)

Calculate statistics about the response times:

    >>> from ely.poundmonitor.tests import display
    >>> display(stats.calculate())
    {'127.0.0.1:8080': (0.5, 1.0, 4.0, 10.0)}

And the results can be nicely printed out to a stream:

    >>> from StringIO import StringIO
    >>> stream = StringIO()
    >>> stats.dump(stream)
    >>> print stream.getvalue()

"""
import time

class Stats(object):

    def __init__(self):
        self.last_date = 0
        self.log = {}

    def record(self, date, backend, delay):
        if date < self.last_date:
            # Assume that the log entries are written in sequential
            # order.
            return
        self.last_date = date
        self.log.setdefault(backend, []).append((date, delay))

    def calculate(self, threshold=0.0):
        result = {}
        for backend, logs in self.log.items():
            response_times = [response_time for date, response_time in logs
                              if date >= threshold]
            response_times.sort()
            n = len(response_times)
            if n == 0:
                continue
            result[backend] = (
                response_times[0],
                response_times[int(n*0.25)],
                response_times[int(n*0.75)],
                response_times[-1],
                )
        return result

    def dump(self, stream):
        for backend, result in self.calculate().items():
            stream.write(backend + '\n')
